package com.esionet.common.api.interceptor;

import com.esionet.common.api.annotation.IgnoreAuth;
import com.esionet.common.api.annotation.RequireAuth;
import com.esionet.common.exception.MyException;
import com.esionet.common.utils.StringUtil;
import com.esionet.common.utils.constants.Constant;
import com.esionet.dao.SysMenuDao;
import com.esionet.dao.SysUserDao;
import com.esionet.entity.SysMenu;
import com.esionet.entity.SysUser;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 * 后台管理-权限(Token)验证
 *
 * @author chenyi
 * @date 2019-10-23 00:38
 */
@Component
public class AdminInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    private SysUserDao sysUserDao;
    @Autowired
    private SysMenuDao sysMenuDao;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        IgnoreAuth ignoreAuth;
        RequireAuth requireAuth;
        if (handler instanceof HandlerMethod) {
            ignoreAuth = ((HandlerMethod) handler).getMethodAnnotation(IgnoreAuth.class);
            requireAuth = ((HandlerMethod) handler).getMethodAnnotation(RequireAuth.class);
        } else {
            return true;
        }

        //如果有@IgnoreAuth注解，则不验证token
        if (ignoreAuth != null) {
            return true;
        }
        //从header中获取token
        String token = request.getHeader("token");
        //如果header中不存在token，则从参数中获取token
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
        }
        //token为空
        if (StringUtils.isBlank(token)) {
            throw new MyException("token不能为空", 401);
        }

        //查询token信息
        SysUser user = sysUserDao.findByToken(token);
        if (user == null) {
            throw new MyException("token失效，请重新登录", 401);
        }

        //验证权限
        if (requireAuth != null) {
            String auth = requireAuth.value();
            if(StringUtils.isNotBlank(requireAuth.value())){
                AuthCheck(user.getUserId(),auth);
            }
        }


        //设置userId到request里，后续根据loginName，获取用户信息
        request.setAttribute(Constant.CURRENT_SYSTEM_USER, user);
        return true;
    }

    //权限校验
    private void AuthCheck(String userId,String auth){
        List<String> permsList;
        //系统管理
        if (Constant.SUPER_ADMIN.equals(userId)) {
            List<SysMenu> menuList = sysMenuDao.getList(null);
            permsList = new ArrayList<>(menuList.size());
            for (SysMenu menu : menuList) {
                permsList.add(menu.getPerms());
            }
        } else {
            permsList = sysUserDao.queryAllPerms(userId);
        }

        //用户权限列表
        Set<String> permsSet = new HashSet<String>();
        for (String perms : permsList) {
            if (StringUtils.isBlank(perms)) {
                continue;
            }
            permsSet.addAll(Arrays.asList(perms.trim().split(",")));
        }
        if (!StringUtil.isEmpty(auth) && !permsSet.contains(auth)) {
            throw new MyException("权限不足,请联系管理员", 405);
        }
    }

}
